package com.siriframe.security.service.impl;

import com.siriframe.entity.Result;
import com.siriframe.security.entity.po.LoginUser;
import com.siriframe.security.service.LoginAndLogoutService;
import com.siriframe.security.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
public class LoginAndLogoutServiceImpl implements LoginAndLogoutService {

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Result login(String username, String password) {
        //登录认证，把用户登录的用户名和密码封装到authenticationToken对象中去
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);

        //authenticationToken对象中
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        //要是验证通过了，这个authenticate对象不会为null的

        //验证用户是否登录成功
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("用户名或密码错误");
        }

        //到这里就是登录成功了
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String userId = loginUser.getUser().getId().toString();
        String token = JwtUtil.createJWT(userId);

        //将用户信息存入Redis
        redisTemplate.opsForValue().set(userId,loginUser);  //注意这里的LoginUser为什么可以直接存入Redis?是因为UserDetails已经序列化过了

        return Result.ok("登录成功","Token : "+token);
    }

    @Override
    public Result logout() {

        //获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        //这里不需要考虑LoginUser存不存在的问题，能进入到这里，都是已经经过了认证的，所以肯定是存在的
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId().toString();

        //删除redis中的值
        redisTemplate.delete(userId);
        return Result.ok("成功退出登录");
    }
}
